import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;


public class Main {
	
	private static final String PUNTAJES = "puntajes_nuevos1.json";
	private static final String RUBIAS_MOROCHAS = "rubias-morochas1.json";
	private static Gson gson = new Gson();
	private static final int CANT_ARGS = 1;
	private static final int ENTRENAMIENTO_PUNTAJES = 1;
	private static final int ENTRENAMIENTO_RUBIAS_MOROCHAS = 2;
	private static final String USERID_ENTRENAMIENTO = "54";
	private static final String METODO_NN = "nn";
	//private static final String METODO_NN_PCA = "nn_pca";
	private static final String PREFIJO_IMAGEN_TEST = "imagen";
	private static final String TEST_DIRECTORY = "test1/";
	private static final String SALIDA = "usuarios_creados.json";
	private static final String TEMP = "file.tmp";
	
	private static void imprimirAyuda() {
		System.out.println("Parámetros inválidos");
		System.out.println("Modo de ejecución: java -jar " +
				"webservice_starter.jar a1");
		System.out.println("a1 = entrenamiento : entero");
		System.out.println("entrenamiento: 1 = Entrenamiento con puntajes");
		System.out.println("entrenamiento: 2 = Entrenamiento rubia-morocha");
	}
	
	private static boolean argumentosValidos(int a1) {
		if (a1 < ENTRENAMIENTO_PUNTAJES || a1 > ENTRENAMIENTO_RUBIAS_MOROCHAS) {
			return false;
		}
		
		return true;
	}

	public static void main(String[] args) {
		
		if (args.length != CANT_ARGS) {
			imprimirAyuda();
			return;
		}
		
		try {
			
			int a1 = Integer.parseInt(args[0]);
			if (!argumentosValidos(a1)) {
				imprimirAyuda();
				return;
			}

			if (a1 == ENTRENAMIENTO_PUNTAJES) {
				crearUsuarios("2");
				entrenarUsuario(USERID_ENTRENAMIENTO, METODO_NN, PUNTAJES);
				//entrenarUsuario(USERID_ENTRENAMIENTO, METODO_NN_PCA, PUNTAJES);
			} else {
				crearUsuarios("1");
				entrenarUsuario(USERID_ENTRENAMIENTO, METODO_NN, 
						RUBIAS_MOROCHAS);
				//entrenarUsuario(USERID_ENTRENAMIENTO, METODO_NN_PCA, 
				//		RUBIAS_MOROCHAS);
			}
			
			WebserviceTester.testGetValidTargets(USERID_ENTRENAMIENTO, "1000");
			
		} catch (NumberFormatException e) {
			imprimirAyuda();
		} catch (URISyntaxException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}
	
	private static Map<String, String> jsonToMap(String filename) {
		
		InputStream is = Main.class.getClassLoader().getResourceAsStream(
				filename);
		BufferedReader in = new BufferedReader(new InputStreamReader(is));
		String line;
		String json = "";

		try {
			while ((line = in.readLine()) != null) {
				json += line;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

		return gson.fromJson(json, 
				new TypeToken<Map<String, String>>() {}.getType());

	}
	
	private static void crearUsuarios(String interes) 
			throws URISyntaxException, IOException {
		
		Map<String, Map<String, String>> usuarios = 
				new HashMap<String, Map<String, String>>();
		InputStream is = Main.class.getClassLoader().getResourceAsStream(
				TEST_DIRECTORY + PREFIJO_IMAGEN_TEST + 
				USERID_ENTRENAMIENTO+".jpg");
		byte[] data = IOUtils.toByteArray(is);
		File file = new File(TEMP);
		org.apache.commons.io.FileUtils.writeByteArrayToFile(file, data); 
		
		//creación de un usuario para ser entrenado. Se crea hombre
		WebserviceTester.testCreateUser(USERID_ENTRENAMIENTO, "0", interes);
		WebserviceTester.testUpdateUserImage(USERID_ENTRENAMIENTO, file);
		WebserviceTester.testSetMethod(USERID_ENTRENAMIENTO, "nn");
		Map<String, String> valores = new HashMap<String, String>();
		valores.put("genderid", "0");
		valores.put("interestedin", interes);
		valores.put("pictureid", 
				PREFIJO_IMAGEN_TEST + USERID_ENTRENAMIENTO+".jpg");
		usuarios.put(USERID_ENTRENAMIENTO, valores);
		
		//creación de 53 mujeres
		for (int i = 1; i <= 53; i++) {
			String s = Integer.toString(i);
			WebserviceTester.testCreateUser(s, "1", "2");
			is = Main.class.getClassLoader().getResourceAsStream(
					TEST_DIRECTORY + PREFIJO_IMAGEN_TEST + 
					s + ".jpg");
			data = IOUtils.toByteArray(is);
			file = new File(TEMP);
			org.apache.commons.io.FileUtils.writeByteArrayToFile(file, data); 
			WebserviceTester.testUpdateUserImage(s, file);
			WebserviceTester.testSetMethod(s, "nn");
			Map<String, String> valores1 = new HashMap<String, String>();
			valores1.put("genderid", "1");
			valores1.put("interestedin", "2");
			valores1.put("pictureid", PREFIJO_IMAGEN_TEST+s+".jpg");
			usuarios.put(s, valores1);
		}
		
		//creación de 21 hombres
		for (int i = 55; i <= 75; i++) {
			String s = Integer.toString(i);
			WebserviceTester.testCreateUser(s, "0", "2");
			is = Main.class.getClassLoader().getResourceAsStream(
					TEST_DIRECTORY + PREFIJO_IMAGEN_TEST + 
					s + ".jpg");
			data = IOUtils.toByteArray(is);
			file = new File(TEMP);
			org.apache.commons.io.FileUtils.writeByteArrayToFile(file, data); 
			WebserviceTester.testUpdateUserImage(s, file);
			WebserviceTester.testSetMethod(s, "nn");
			Map<String, String> valores1 = new HashMap<String, String>();
			valores1.put("genderid", "0");
			valores1.put("interestedin", "2");
			valores1.put("pictureid", PREFIJO_IMAGEN_TEST+s+".jpg");
			usuarios.put(s, valores1);
		}
		
		FileUtils.writeStringToFile(new File(SALIDA),gson.toJson(usuarios));
		
	}
	
	private static void entrenarUsuario(String id, String metodo, 
			String filename) {
		
		Map<String, String> puntajes = jsonToMap(filename);
		WebserviceTester.testSetMethod(id, metodo);
		
		for (String trainingid : puntajes.keySet()) {
			String puntaje = puntajes.get(trainingid);
			WebserviceTester.testTrainUserBot(id, trainingid, puntaje);
		}
		
	}

}
